from mtp.lib.base import *
from mako.exceptions import TopLevelLookupException
from mtp.lib.pageaction import PageAction
#from mtp.lib import pageetags

from lxml import html
from lxml import etree

import logging
log = logging.getLogger(__name__)

class PagesController(BaseController):
    """REST Controller styled on the Atom Publishing Protocol"""

    def _update(self, id, format='html'):
        action = request.POST.get('action').lower()
        if action == 'preview':
            return self.preview(format=format)
        elif action == 'cancel':
            if id:
                redirect_to(h.url_for('page', id=id))
            else:
                redirect_to(h.url_for('home'))
        else:    
            title = request.POST.get('title', '').strip()
            body = request.POST.get('body', '').strip()
            comment = request.POST.get('comment', '').strip()

            c.page, c.page_rev = model.Page.add(title, session.get('user'), 
                                                body, comment)

            for proc in config['mtp.edit_page.processors']:
                proc()

            redirect_to(h.url_for('page', id=c.page.urlTitle()))
    
    @needs_perm('page', 'list')
    def index(self, format='html'):
        """GET /pages: All items in the collection."""
        # url_for('pages')
        c.pages = model.Page.getAll()
        return render('/pages/list.%s' % format)

    @needs_perm('page', 'create')
    def create(self, format='html'):
        """POST /pages: Create a new item."""
        # url_for('pages').
        return self._update(None, format)

    @needs_perm('page', 'create')
    def new(self, format='html'):
        """GET /pages/new: Form to create a new item."""
        # url_for('new_page')

        if request.params.has_key('last_page'):
            c.last_page = model.Page.getByTitle(request.params['last_page'])

        return self._edit()

    @needs_perm('page', 'create')
    def preview(self, format='html'):
        # url_for('preview_new_page')
        c.page = model.Page(
            title=request.POST['title'],
        )
        c.page_rev = model.PageRevision(
            body=request.POST['body'],
            comment=request.POST['comment'],
        )
        c.preview = True
        
        return self._edit()

    @needs_perm('page', 'edit')
    def update(self, id, format='html'):
        """PUT /pages/id: Update an existing item."""
        #    h.form(h.url_for('page', id=ID),
        #           method='put')
        return self._update(id, format)

    @needs_perm('page', 'delete')
    def delete(self, id, format='html'):
        """DELETE /pages/id: Delete an existing item."""
        #    h.form(h.url_for('page', id=ID),
        #           method='delete')
        page = model.Page.getByTitle(id)
        if not page:
            abort(404)
        page.delete()

        redirect_to(h.url_for('home'))

    @needs_perm('page', 'view')
    def show(self, id, format='html'):
        """GET /pages/id: Show a specific item."""
        # url_for('page', id=ID)
        page = model.Page.getByTitle(id)

        if not page:
            c.title = id
            try:
                return render('/pages/missing.%s' % format)
            except TopLevelLookupException:
                abort(404)

        if request.params.has_key('revision'):
            page_rev = page.getRevision(int(request.params['revision']))
        else:
            page_rev = page.getLatest()

        c.page = page

        if format != 'html':
            if not config['mtp.plugin_formatters'].has_key(format):
                abort(404)
            def _formatter_cmp(a, b):
                return cmp(a.quality, b.quality)

            formatters = config['mtp.plugin_formatters'][format]
            formatters.sort(_formatter_cmp, reverse=True)
            if not formatters:
                abort(404)
            formatter = formatters[0]
            return formatter(page, page_rev)

        urltitle = page.urlTitle()

        c.page_rev = page_rev
        c.page_actions.extend([
            PageAction("Create", h.url_for('new_page', last_page=urltitle),
                        permission=('page', 'create')),
            PageAction("Edit", h.url_for('edit_page', id=urltitle), 
                        permission=('page', 'edit')),
            PageAction("Delete", h.url_for('page', id=urltitle), method='DELETE',
                        permission=('page', 'delete')),
        ])

        #etag_cache('%s%s%s' % (c.page_rev.title, c.page_rev.revision, 
        #                       hash(tuple((pa[0] for pa in c.page_actions)))))

        #etag_cache(pageetags.page_etag(urltitle))

        return render('/pages/view.%s' % format)

    @needs_perm('page', 'edit')
    def edit(self, id, format='html'):
        """GET /pages/id;edit: Form to edit an existing item."""
        # url_for('edit_page', id=ID)
        c.page = model.Page.getByTitle(id)

        if not c.page:
            abort(404)

        c.page_rev = c.page.getLatest()
        return self._edit()

    def _edit(self):
        def getcontent(key):
            ret = []
            for thing in config[key]:
                if callable(thing):
                    thing = thing()
                if thing:
                    ret.append(thing)
            return ret

        c.edit_content_prepend = getcontent('mtp.edit_page.content.prepend')
        c.edit_content_insert = getcontent('mtp.edit_page.content.insert')
        c.edit_content_append = getcontent('mtp.edit_page.content.append')


        return render('/pages/edit.html')
   


